Java JavaScript Python C# C C++ Go Kotlin PHP Swift R Ruby TypeScript Scala SQL Perl rust VisualBasic Matlab Julia

Inheritance → Multiple Inheritance

Inheritance

Multiple Inheritance

Multiple inheritance, a powerful feature of object-oriented programming (OOP), allows a class to inherit attributes and methods from multiple parent classes. Python directly supports multiple inheritance, unlike some languages like Java which only allow single inheritance (a class can inherit from only one parent class). This capability offers flexibility but also presents potential complexities. Let's explore this with detailed explanations and examples.

How it works!

When a class `C` inherits from multiple parent classes `A` and `B` (written as `class C(A, B):`), `C` gains access to all the attributes and methods of both `A` and `B`. If there's a name conflict (both `A` and `B` have a method with the same name), Python's Method Resolution Order (MRO) determines which method is called.

Method Resolution Order (MRO)

The MRO is a crucial aspect of multiple inheritance. It dictates the order in which Python searches for methods and attributes when a method call is made. Python uses the C3 linearization algorithm to determine the MRO, ensuring a consistent and predictable order. You can inspect the MRO using the `__mro__` attribute or the `mro()` method of a class. Example 1: Simple Multiple Inheritance
Simple multiple inheritance example class Animal: def __init__(self, name): self.name = name def speak(self): print("Generic animal sound") class Flyer: def fly(self): print("Flying...") class Bird(Animal, Flyer): # Inherits from Animal and Flyer def __init__(self, name, species): super().__init__(name) # Call Animal's __init__ self.species = species def speak(self): # Overriding the speak method print("Tweet!") my_bird = Bird("Tweety", "Canary") my_bird.speak() my_bird.fly() print(my_bird.name)

Output

Tweet! Flying... Tweety
Here, `Bird` inherits `speak` and `__init__` from `Animal` and `fly` from `Flyer`. The `super()` call ensures proper initialization of the parent class attributes. Note how the MRO shows the search order: `Bird`, `Animal`, `Flyer`, then `object` (the base class of all classes). If `Bird` didn't override `speak`, `Animal`'s `speak` would be used.
Example 2: Handling Name Conflicts
Handling Name Conflicts in multiple inheritance class A: def method(self): print("Method from A") class B: def method(self): print("Method from B") class C(A, B): pass my_c = C() my_c.method() print(C.__mro__)

Output

Method from A (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
This demonstrates how MRO resolves name conflicts. Since `A` is listed before `B` in the inheritance order (`C(A,B)`), `A`'s `method` is called. Changing the order to `C(B,A)` would result in `B`'s method being called.
Example 3: Diamond Problem The "diamond problem" arises when a class inherits from two classes that share a common ancestor. Let's illustrate:
Diamond Problem in multiple inheritance class Grandparent: def method(self): print("Grandparent's method") class Parent1(Grandparent): #No changes to the method pass class Parent2(Grandparent): #No changes to the method pass class Child(Parent1, Parent2): pass my_child = Child() my_child.method() print(Child.__mro__)

Output

Grandparent's method (<class '__main__.Child'>, <class '__main__.Parent1'>, <class '__main__.Parent2'>, <class '__main__.Grandparent'>, <class 'object'>)
Here, `Child` inherits from both `Parent1` and `Parent2`, which both inherit from `Grandparent`. The MRO ensures that `Grandparent`'s method is called only once, avoiding ambiguity and resolving the diamond problem effectively.
Important Considerations Complexity: Multiple inheritance can increase code complexity, making it harder to understand and maintain. Use it judiciously. Readability: Well-named classes and methods are essential for readability in multiple inheritance scenarios. Testing: Thorough testing is crucial to ensure the correctness of method resolution and avoid unexpected behavior. Multiple inheritance is a powerful tool, but it demands careful design and understanding. By mastering the MRO and understanding the potential complexities, you can leverage its benefits while mitigating its risks. Always prioritize clarity and maintainability in your code.

Tutorials